package com.mvc.security.web;

import java.io.IOException;
import java.net.PasswordAuthentication;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.mvc.framework.service.PageManager;
import com.mvc.framework.util.ListUtils;
import com.mvc.framework.util.MessageUtils;
import com.mvc.framework.web.PageController;
import com.mvc.portal.service.LoginErrorManager;
import com.mvc.security.SecurityConstants;
import com.mvc.security.model.PasswordChanged;
import com.mvc.security.model.Role;
import com.mvc.security.model.User;
import com.mvc.security.model.UserRole;
import com.mvc.security.service.DepartmentManager;
import com.mvc.security.service.PasswordChangedManager;
import com.mvc.security.service.RoleManager;
import com.mvc.security.service.UserManager;
import com.mvc.security.service.UserRoleManager;
import com.mvc.security.util.SecurityUtils;

@Controller
@RequestMapping("/user")
public class UserController extends PageController<User> {
	 private static final Logger LOGGER = Logger.getLogger(UserController.class);
	 
	private static final String BASE_DIR = "security/";
	@Autowired
	private UserManager<User> userManager;
	@Autowired
	private RoleManager roleManager;
	@Autowired
	private UserRoleManager userRoleManager;
	@Autowired
	private DepartmentManager departmentManager;
	@Autowired
	private LoginErrorManager loginErrorManager;
	@Autowired
	private PasswordChangedManager passwordChangedManager;

	@RequestMapping("/editUserRole/{userId}")
	public String editUserRole(ModelMap modelMap, @PathVariable Integer userId) {
		User user = userManager.getUserByUserId(userId);
		List<Role> allRoles = roleManager.getAll();
		List<Role> haveRoles = roleManager.getRolesByUserId(userId);
		List<Role> notHaveRoles = ListUtils.filter(allRoles, haveRoles);
		modelMap.addAttribute("notHaveRoles", notHaveRoles);
		modelMap.addAttribute("haveRoles", haveRoles);
		modelMap.addAttribute("user", user);
		return BASE_DIR + "editUserRole";
	}

	@RequestMapping("/saveUserRole")
	public String saveUserRole(HttpServletRequest request, Integer userId) {
		String[] roleIds = request.getParameterValues("menuId");
		if (roleIds == null || roleIds.length == 0) {
			userRoleManager.deleteUserRoleByUserId(userId);
		} else {
			List<UserRole> userRoles = new ArrayList<UserRole>(roleIds.length);
			for (String roleId : roleIds) {
				UserRole userRole = new UserRole();
				userRole.setRoleId(Integer.valueOf(roleId));
				userRole.setUserId(userId);
				userRoles.add(userRole);
			}
			userRoleManager.saveUserRolesByUserId(userRoles,userId);
		}
		return "redirect:/user/editUserRole/" + userId + getMessage("保存成功",request);
	}

	@RequestMapping("/changePassword")
	public String changePassword() {
		return BASE_DIR + "changePassword";
	}

	@RequestMapping("/savePassword")
	public String savePassword(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String oldPlainPassoed = request.getParameter("oldPassword");
		String newPlainPassword = request.getParameter("newPassword");
		String confirmPalinPassword = request.getParameter("confirmPassword");
		String resultMessage = "account.updatePassword.Failed";
		if (StringUtils.isNotBlank(newPlainPassword)) {
			if (newPlainPassword.equals(confirmPalinPassword)) {
				Integer userId = (Integer) request.getSession().getAttribute(SecurityConstants.USER_ID);
				User user = userManager.getUserByUserId(userId);
				if (null != user) {
					if (SecurityUtils.generatePassword(oldPlainPassoed).equals(user.getPassword())) {
						user.setPassword(SecurityUtils.generatePassword(newPlainPassword));
						userManager.updatePassword(user);
						PasswordChanged changed = new PasswordChanged();
						changed.setUserId(user.getObjectId());
						changed.setChangeDate(new Date());
						passwordChangedManager.save(changed);
						resultMessage = "account.updatePaddword.Success";
					} else {
						resultMessage = "account.updatePaddword.oldPasswordWrong";
					}
				} else {
					resultMessage = "account.updatePaddword.accountNotExist";
				}
			} else {
				resultMessage = "account.updatePaddword.twoPasswordNotTheSame";
			}
		} else {
			resultMessage = "account.updatePaddword.newPasswordIsBlank";
		}
		return "redirect:changePassword" + getMessage(resultMessage,request);
	}

	protected String handleEdit(HttpServletRequest request, HttpServletResponse response, Integer id) throws Exception {
		if (null != id) {
			User entity = userManager.getUserWithDepartment(id);
			request.setAttribute("entity", entity);
		}
		request.setAttribute("userDepartments", departmentManager.getAll());
		return getFileBasePath() + "edit" + getActualArgumentType().getSimpleName();
	}

	protected String handleSave(HttpServletRequest request, ModelMap modelMap, User user) throws Exception {
		User exist = userManager.checkIfExistsUser(user);
		if(exist!=null){
			throw new RuntimeException(MessageUtils.getMessage("user.loginNameDuplicate", request));
		}
		return super.handleSave(request, modelMap, user);
	}
	

	@RequestMapping("/resetPassword/{id}")
	public String resetPassword(HttpServletRequest request, @PathVariable Long id) {
		request.setAttribute("id", id);
		return BASE_DIR + "resetPassword";
	}

	@RequestMapping(value = "/saveReset", method = RequestMethod.POST)
	public String saveReset(HttpServletRequest request, User user) {
		String newPlainPassword = request.getParameter("newPassword");
		String message;
		if (StringUtils.isNotBlank(newPlainPassword)) {
			user.setPassword(SecurityUtils.generatePassword(newPlainPassword));
			userManager.updatePassword(user);
			message = MessageUtils.getMessage("user.password.reset.success", request);
		} else {
			message = MessageUtils.getMessage("user.password.reset.blank", request);
		}
		return "redirect:resetPassword/" + user.getId() + getMessage(message,request);
	}
	
	@RequestMapping(value = "/unlock/{loginName}", method = RequestMethod.POST)
	public String unlock(@PathVariable String loginName,ModelMap modelMap) throws Exception {
		loginErrorManager.updateLoginErrorStatus(loginName);
		modelMap.put("result", "true");
		return "jsonView";
	}

	@Override
	public PageManager getEntityManager() {
		return userManager;
	}

	@Override
	public String getFileBasePath() {
		return BASE_DIR;
	}

}
